using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using JwtRegisteredClaimNames = Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames;

namespace WebApplication1.Auth;

public class JWTHelp
{
    private readonly IConfigurationSection _configuration;

    public JWTHelp(IConfigurationSection configuration)
    {
        _configuration = configuration;
    }
    public string CreateToken()
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, "u_admin"), //HttpContext.User.Identity.Name
            new Claim(ClaimTypes.Role, "r_admin"), //HttpContext.User.IsInRole("r_admin")
            new Claim(JwtRegisteredClaimNames.Jti, "admin"),
            new Claim("Username", "Admin"),
            new Claim("Name", "超级管理员")
        };
        
        //2。从 appsettings.json 中读取密钥
        var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecretKey"]));
        
        //3 选择加密算法
        var algorithm = SecurityAlgorithms.HmacSha256;
        
        //4.生成Creadentials
        var signingCredentals = new SigningCredentials(secretKey, algorithm);
        
        //根据上面生成 Creadentials 和 claims 生成 JWT

        var jwtSecurityToken = new JwtSecurityToken(
            issuer:  _configuration["Issuer"],
            audience : _configuration["Audience"],
            claims : claims,
            notBefore: DateTime.Now,
            expires: DateTime.Now.AddSeconds(3000),
            signingCredentials: signingCredentals
            );
        
        var token = new JwtSecurityTokenHandler().WriteToken(jwtSecurityToken);
        return token;
    }

    public string RefreshToken(string token)
    {
        try
        {
            //TODO: 刷新token
            var handler = new JwtSecurityTokenHandler();
        
            var jwtToken = handler.ReadJwtToken(token);
        
            // 计算剩余时间
            TimeSpan remaining = jwtToken.ValidTo - DateTime.UtcNow;

            // 判断是否快过期
            if (remaining < TimeSpan.FromSeconds(10))
            {
                // token快过期了，可以刷新
                return CreateToken();
            }
          
            return token;
            
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
            throw;
        }
    }
}